import java.io.*;
import java.util.*;

import javax.swing.JOptionPane;
import java.util.Random;

public class jRead {
	private String alpha;
	private String key = "";
	private String encText;
	private String plnText;
	private boolean odd = true;
	/**
	 * Writes the key to an output file.
	 * @param fileName - path of the file to be written to
	 */
	public void exportKey(String fileName)
	{
		PrintWriter writeKey = null;
		
		try {
			writeKey = new PrintWriter(fileName);
			} catch (FileNotFoundException e2) {
			// TODO Auto-generated catch block
		e2.printStackTrace();
		}//open the key file
		writeKey.println(key);//and save our current 'key' to it
		writeKey.close();
		
		
	}
	
	/**
	 * Switches the alphabet to a different format.
	 * Formats include desktop versions and mobile versions.
	 * @param alphaDB
	 * @return weather a database was found matching the string
	 */
	public boolean switchAlphabet(String alphaDB)
	{
		if (alphaDB.equals("13"))
		{
			alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890	€„ŠŒŽ™©¡®°¥¿¶éÑØñæ`~+=-_!@#$%^&*”(){}:;[]<>,.?/|'\\ " + '"';
			return true;
		}
		//if nothing was found
	return false;		
			
	}
	
	public jRead() {

		System.out.println("jRead Library v1.3");
		alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890	€„ŠŒŽ™©¡®°¥¿¶éÑØñæ`~+=-_!@#$%^&*”(){}:;[]<>,.?/|'\\ " + '"'; // needs
																																				// \
																																				// and
																																				// ".
		// db System.out.println(alpha);

	}

	// TODO add method to read key from text file
	// TODO Remove above line, once GUI is done, the pass will be sent from
	// there.

	// db
	// System.out.println("Alphabet:\n"+alpha+"\nnumber of elements: "+alpha.length());

	public String encrypt(String inText,String pass)
	{

		inText=inText.replaceAll("\\s*[\\r\\n]+\\s*", "¶").trim();

		int x=0;
		String crypt="";
		
		odd=true;
		int keyPos=0;
		int pos=0;
		odd=true;
		int pasPos=0;//current position in password
//db	System.out.println("getting offset:");
		 //now get the offset,values of each char in the passphrase

//db		System.out.println("Final offset: "+offset+" will be applied to the input");
		x=0;
		
		while (x<inText.length() )
		{
			pos = alpha.indexOf(inText.charAt(x));// look up the letter in slot x, and find it in alpha, save it's location in 'pos'
			if (pos==-1)
			{ //if not found
				System.out.println("I have no idea what '"+inText.charAt(x)+"' is!");
				return "error: unrecognized character"; //let the GUI know.					
			}
			
			if (pass.length() > 0)//if there is a password
			{
		     //db  System.out.println("password: "+pass+"posistion: "+pasPos);
				pos=pos+alpha.indexOf(pass.charAt(pasPos));  //add the value of as single character from the password to the the new offset
				//First we well read each char in the password, then we'll add it to the offset that determines the encrypted letter
				//once we run out of password letters, we'll read the password backwards (for lulz) 
				if (odd==true)//odd passes
					pasPos++; //next time we'll read from the next  character (forward pass)
				if (odd==false)//even passes
					pasPos--;
				//reset values	
				if (pasPos >= pass.length())// if we reach the end, we were reading forward
				{
					odd=false; //so lets go backwards this time
					pasPos = pass.length()-1;
				}
				if (pasPos < 0) // if we were going backwards,
				{
					odd=true; //lets go forward
					pasPos=0;
				}
			}                      
			
	    //now we use the keyfile
			if (keyPos>key.length()-1 ) //if we reach the end of the key file
				keyPos=0;  //start back at the begining
			pos=pos+alpha.indexOf(key.charAt(keyPos)); //here we look up what letter in slot 'keyPos' in our keyFile one we find it
	                                 //once we have it, we find out it's position in the alphabet, and add that to the pos
//db   System.out.println("Key offset for: "+keyPos+" is: "+alpha.indexOf(key.charAt(keyPos)));
			keyPos++;
	     
			while (pos>alpha.length()-1||pos<0)
			{                                   //If out posistion is larger than out alphabet, or a negitive number,
				if (pos>alpha.length()-1 ) //take some off to make it fit our alphabet
					pos=pos-alpha.length(); //we'll take off one 'length' each time, that's equal to it scrolling
	                                //though the whole alphabet. it will repeat as needed.
				if (pos<0)               //if it's to small we'll add  the lenght to it.
					pos=pos+alpha.length();//The point of this part is, if you were looking at say -5 for posistion
	                    //their is no -5'th letter in the alphabet, if we added 6, yes it would be positive             
	                    //but if th next pos was -12 then -6 would no longer work. so we add the lenght of 
	                    //the alphabet string, so, it count as one full rotation(scrolling through all 108 or so letters
	                    //and you be in the same spot as before (since it's one full rotation) but the number will be positive
		
			} //Loop if needed (such as if the negitive number was so big, even one full rotation was not enough to get it above -1, ect.
	    
	    //now that we have the location of our new letter/symbol/number that is part
	    //of the encrypted text, lets go ahead and add it.
	    crypt=crypt+alpha.charAt(pos);
	    x++;
	    }
	  return crypt;			
	}

	public String decrypt(String inText, String pass) 
	{

		if 	(switchAlphabet(inText.substring(1,2))==true)
			inText = inText.substring(3, inText.length() - 1);// trim the label
		else //if it's not fount they may have hidden the label
			{
			if ((inText.charAt(0)=='<')&&(inText.charAt(inText.length()-1)=='>')) //if it uses the old <encrypted text> style, trim that too!
				inText = inText.substring(1, inText.length() - 1);
			}
	
			
		String dcrypt = "";
		int x = 0;
		
		odd = true; // it starts as false, because this time, becuase we need
		int pasPos=0;				// to do the opisate of the enc'
		int keyPos = 0;
		int pos = 0;

		// db System.out.println("getting offset:");
		// now get the offset,values of each char in the passphrase

			x=0;

			while (x<inText.length() )
			{
				pos = alpha.indexOf(inText.charAt(x));// look up the letter in slot x, and find it in alpha, save it's location in 'pos'
				if (pos==-1)
				{ //if not found
					System.out.println("I have no idea what '"+inText.charAt(x)+"' is!");
					return "error: unrecognized character"; //let the GUI know.					
				}
				
				if (pass.length() > 0)//if there is a password
				{
					
					pos=pos-alpha.indexOf(pass.charAt(pasPos));  //add the value of as single character from the password to the the new offset
					//First we well read each char in the password, then we'll add it to the offset that determines the encrypted letter
					//once we run out of password letters, we'll read the password backwards (for lulz) 
					if (odd==true)//odd passes
						pasPos++; //next time we'll read from the next  character (forward pass)
					if (odd==false)//even passes
						pasPos--;
					//reset values	
					if (pasPos >= pass.length())// if we reach the end, we were reading forward
					{
						odd=false; //so lets go backwards this time
						pasPos = pass.length()-1;
					}
					if (pasPos < 0) // if we were going backwards,
					{
						odd=true; //lets go forward
						pasPos=0;
					}
				}                      
					
			// now we use the keyfile
			if (keyPos > key.length() - 1) // if we reach the end of the key
											// file
				keyPos = 0; // start back at the begining

			pos = pos - alpha.indexOf(key.charAt(keyPos)); // here we look up
															// what letter in
															// slot 'keyPos' in
															// our keyFile one
															// we find it
			// once we have it, we find out it's position in the alphabet, and
			// add that to the pos
			// db
			// System.out.println("Key offset for: "+keyPos+" is: "+alpha.indexOf(key.charAt(keyPos)));
			keyPos++;

			while (pos > alpha.length() || pos < 0) { // If out position is
														// larger than out
														// alphabet, or a
														// negitive number,
				if (pos > alpha.length()) // take some off to make it fit our
											// alphabet
					pos = pos - alpha.length(); // we'll take off one 'length'
												// each time, that's equal to it
												// scrolling
				// though the whole alphabet. it will repeat as needed.
				if (pos < 0) // if it's to small we'll add the length to it.
					pos = pos + alpha.length();// The point of this part is, if
												// you were looking at say -5
												// for posistion
				// their is no -5'th letter in the alphabet, if we added 6, yes
				// it would be positive
				// but if th next pos was -12 then -6 would no longer work. so
				// we add the lenght of
				// the alphabet string, so, it count as one full
				// rotation(scrolling through all 108 or so letters
				// and you be in the same spot as before (since it's one full
				// rotation) but the number will be positive

			} // Loop if needed (such as if the negative number was so big, even
				// one full rotation was not enough to get it above -1, ect.
			if (pos == alpha.length())
				pos--;

			// now that we have the location of our new letter/symbol/number
			// that is part
			// of the encrypted text, lets go ahead and add it.
			// db System.out.println("Position: "+pos);
			dcrypt = dcrypt + alpha.charAt(pos);
			// dcrypt=dcrypt+alpha.substring(pos,1);
			x++;
		}
		dcrypt = dcrypt.replaceAll("¶", "\n").trim();
		return dcrypt;
	}

	/**
	 * @return the encText
	 */
	public String getEncText() {
		return encText;
	}

	/**
	 * @param newKey
	 *            The new keyfile
	 */
	public void changeKey(String newKey) {
		key = newKey;
	}

	/**
	 * @param encText
	 *            the encText to set
	 */
	public void setEncText(String newEncText) {
		encText = newEncText;
	}

	/**
	 * @return the plnText
	 */
	public String getPlnText() {
		return plnText;
	}

	public String mkKey(int Len) { // make a key sting that is 'Len' chars long
		Random rnd = new Random();// make new random number generator 'rnd'
		int x = 0;
		key = "";
		while (x < Len) // loop this for as many char's as they asked for
		{
			key = key + alpha.charAt(rnd.nextInt(alpha.length())); // pick a
																	// random
																	// letter
																	// from our
																	// alphabet,
																	// and add
																	// it to the
																	// key file
			x++;
		}
		return key;
	}

	/**
	 * @param plnText
	 *            the plnText to set
	 */
	public void setPlnText(String newPlnText) {
		plnText = newPlnText;
	}
}
